package com.wendy.authentication;

import com.wendy.mapper.AuthorityMapper;
import com.wendy.mapper.RoleMapper;
import com.wendy.model.Authority;
import com.wendy.model.Role;
import com.wendy.utils.Constants;
import com.wendy.utils.RequestUriHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author zhuwending
 */
@Component
public class UserInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private AuthorityMapper authorityMapper;

    /**
     * 此方法是为了判定用户请求的url 是否在权限表中，如果在权限表中，则返回给 decide 方法，用来判定用户是否有此权限。如果不在权限表中则放行。
     *
     * @param o object
     * @return Collection
     * @throws IllegalArgumentException e
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        HttpServletRequest request = ((FilterInvocation) o).getRequest();
        Collection<ConfigAttribute> collection = new ArrayList<>(16);
        String uri = request.getRequestURI();
        uri = RequestUriHandler.handlerUri(uri);
        if (!RequestUriHandler.needPermissions(uri)) {
            ConfigAttribute attribute = new SecurityConfig("role");
            collection.add(attribute);
        }
        if (uri.startsWith(Constants.MENU_PATH)) {
            List<Role> roles = roleMapper.selectRoleByMenuPath(uri);
            if (roles != null && roles.size() > 0) {
                roles.forEach(role -> collection.add(new SecurityConfig(role.getCode())));
            }
        } else {
            List<Authority> authorities = authorityMapper.selectAuthorityByResourceUri(uri);
            if (authorities != null && authorities.size() > 0) {
                authorities.forEach(authority -> collection.add(new SecurityConfig(authority.getPermissions())));
            }
        }
        return collection;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return new ArrayList<>(0);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
